<?php
/**
 * 短信通用类，使用阿里云短信服务api
 * User: xp
 * Date: 2020/1/10
 * Time: 11:52
 */

namespace app\common\lib;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use app\exception\IndexException;
use App\Exceptions\UserException;

class Sms
{
    //阿里云api的密钥身份验证信息
    protected $accessKeyId ="";//'LTAI4FtAJoFyYMrjUkmoDiqE';
    protected $accessSecret = "";

    protected $errorStr = '';
    protected $errorNo = '';

    //短信验证码签名名称
    protected $authCodeSignName = '';
    //短信验证码模板名称
    protected $authCodeTemplateCode = '';

    //短信通知签名名称
    protected $noticeSignName = '';
    //短信通知模板名称
    protected $noticeTemplateCode = '';

    //短信推广签名名称
    protected $semSignName = '';
    //短信推广模板名称
    protected $semTemplateCode = '';

    //短信批量发送模板名称
    protected $batchTemplateCode = '';
    //带入需要的配置信息
    public function __construct($accessKeyId="",$accessSecret=""){
        $this->accessKeyId= $accessKeyId;
        $this->accessSecret= $accessSecret;
    }
    /**
     * 发送验证码
     * @param srtring $phonenumbers
     * @param srtring $code
     * @param array $param
     * @return array|bool
     * @throws ClientException
     * @throws UserException
     */

    public function sendAuthCode($phonenumbers,$code,$param=[])
    {
        try{
            if(empty($phonenumbers)){
                throw new IndexException(4020,'手机号码错误');
            }
            if(preg_match('/^[1]([1-9])[0-9]{9}$/',$phonenumbers)==false){
                throw new IndexException(4020,'手机号码错误');
            }
            if(empty($code)){
                throw new IndexException(4020,'验证码不能为空');
            }

            $params = [];
            $params['signName']  = $param['signName']??$this->authCodeSignName;
            $params['templateCode'] = $param['templateCode']??$this->authCodeTemplateCode;
            $params['templateparam'] = ['code'=>$code];
            $params['phonenumbers'] = $phonenumbers;

            //发送
            return $this->sendSms($params);
        }catch (IndexException $e) {
            $this->setError($e->getCode(),$e->getMessage());
            return false;
        }
    }

    /**
     * 发送短信通知
     * @param $param
     * @param $phonenumbers
     * @return array|bool
     * @throws ClientException
     */
    public function sendNoticeSms($phonenumbers,$param)
    {
        try{
            if(empty($phonenumbers)){
                throw new IndexException(2200);
            }
            if(preg_match('/^[1]([3-9])[0-9]{9}$/',$phonenumbers)==false){
                throw new IndexException(2202);
            }
            if(empty($param['templateparam'])){
                throw new IndexException(2201);
            }
            $param['signName']  = $param['signName'] ? $param['signName'] : $this->noticeSignName;
            $param['templateCode'] = $param['templateCode']? $param['templateCode'] : $this->noticeTemplateCode;
            $param['templateparam'] = $param['templateparam'];
            $param['phonenumbers'] = $phonenumbers;

            //发送
            return $this->sendSms($param);
        }catch (IndexException $e) {
            $this->setError($e->getCode(),$e->getMessage());
            return false;
        }
    }

    /**
     * 发送短信推广
     * @param $param
     * @return array|bool
     * @throws ClientException
     */
    public function sendSemSms($param)
    {
        try{
            if(empty($phonenumbers)){
                throw new IndexException(2200);
            }
            if(preg_match('/^[1]([3-9])[0-9]{9}$/',$phonenumbers)==false){
                throw new IndexException(2202);
            }
            if(empty($param['templateparam'])){
                throw new IndexException(2201);
            }
            $param['signName']  = $param['signName'] ? $param['signName'] : $this->semSignName;
            $param['templateCode'] ? $param['templateCode'] : $this->semTemplateCode;
            $param['templateparam'] = $param['templateparam'];
            $param['phonenumbers'] = $phonenumbers;

            //发送
            return $this->sendSms($param);
        }catch (IndexException $e) {
            $this->setError($e->getCode(),$e->getMessage());
            return false;
        }
    }

    /**
     * 发送短信   api: https://api.aliyun.com/new#/?product=Dysmsapi&version=2017-05-25&api=SendSms&tab=DEMO&lang=PHP
     * @param $param
     * @return array|bool
     * @throws ClientException
     */
    protected function sendSms($param)
    {
        try {
            AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessSecret)
                ->regionId('cn-hangzhou')
                ->asDefaultClient();

            $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')
                // ->scheme('https') // https | http
                ->version('2017-05-25')
                ->action('SendSms')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => "cn-hangzhou",
                        'PhoneNumbers' => $param['phonenumbers'],
                        'SignName' => $param['signName'],
                        'TemplateCode' => $param['templateCode'],
                        'TemplateParam' => json_encode($param['templateparam']),
                    ],
                ])
                ->request();

            return $result->toArray();

        } catch (ClientException $e) {
            $this->setError($e->getErrorCode(), $e->getErrorMessage());
            return false;
        } catch (ServerException $e) {
            $this->setError($e->getErrorCode(), $e->getErrorMessage());
            return false;
        }
    }

    /**
     * 批量发送短信 api: https://api.aliyun.com/new#/?product=Dysmsapi&version=2017-05-25&api=SendBatchSms&params={}&tab=DOC&lang=PHP
     * @param $param
     * @return bool
     */
    public function batchSendSms($param)
    {
        try{
            if(empty($param['phonenumbers'])){
                throw new IndexException(2200);
            }
            $phonenumbers= [];
            //多个手机号用数组表示 如：["15900000000","13500000000"]
            foreach ($param['phonenumbers'] as $phonenumber){
                if(preg_match('/^[1]([3-9])[0-9]{9}$/',$phonenumber)==false){
                    throw new IndexException(2202);
                }
                $phonenumbers[] = $phonenumber;
            }
            if(empty($phonenumbers)){
                throw new IndexException(2200);
            }
            $param['PhoneNumberJson'] = json_encode($phonenumbers);

            //1，短信签名名称，JSON数组格式。
            //2，请在控制台签名管理页面签名名称一列查看。
            //3，说明 必须是已添加、并通过审核的短信签名；且短信签名的个数必须与手机号码的个数相同、内容一一对应。
            $param['SignNameJson'] = json_encode($param['signNameJson']);

            //短信模板变量对应的实际值，JSON格式。
            //说明 如果JSON中需要带换行符，请参照标准的JSON协议处理；且模板变量值的个数必须与手机号码、签名的个数相同、内容一一对应，
            //表示向指定手机号码中发对应签名的短信，且短信模板中的变量参数替换为对应的值。
            $param['TemplateParamJson'] = json_encode($param['templateparam']);

            $param['TemplateCode'] ? $param['templateCode'] : $this->batchTemplateCode;

            AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessSecret)
                ->regionId('cn-hangzhou')
                ->asDefaultClient();


            $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')
                // ->scheme('https') // https | http
                ->version('2017-05-25')
                ->action('SendBatchSms')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => "cn-hangzhou",
                        'PhoneNumberJson' => $param['PhoneNumberJson'],
                        'SignNameJson' => $param['SignNameJson'],
                        'TemplateCode' => $param['TemplateCode'],
                        'TemplateParamJson' => $param['TemplateParamJson'],
                    ],
                ])
                ->request();

            return $result->toArray();
        }catch (IndexException $e){
            $this->setError($e->getCode(),$e->getMessage());
            return false;
        }catch (ClientException $e) {
            $this->setError($e->getErrorCode(), $e->getErrorMessage());
            return false;
        } catch (ServerException $e) {
            $this->setError($e->getErrorCode(), $e->getErrorMessage());
            return false;
        }

    }

    public function setError($errorNo,$errorStr)
    {
        $this->errorNo = $errorNo;
        $this->errorStr = $errorStr;
        return false;
    }

    public function getError()
    {
        return [$this->errorNo, $this->errorStr];
    }

    public function querySendDetails($phoneNumber,$sendDate,$pageSize,$currentPage,$BizId){
        AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessSecret)
            ->regionId('cn-hangzhou')
            ->asDefaultClient();

        try{
        $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')
                // ->scheme('https') // https | http
                ->version('2017-05-25')
                ->action('QuerySendDetails')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => "cn-hangzhou",
                        'PhoneNumber' => $phoneNumber,
                        'SendDate' => $sendDate,
                        'PageSize' => $pageSize,
                        'CurrentPage' => $currentPage,
                        'BizId' => $BizId,
                    ],
                ])
                ->request();
           return $result->toArray();
        } catch (ClientException $e) {
            $this->setError($e->getCode(),$e->getMessage());
            return false;
        } catch (ServerException $e) {
            $this->setError($e->getCode(),$e->getMessage());
            return false;
        }
    }
}